import 'dart:io';
import 'dart:isolate';
import 'dart:ui';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bilibili/core/extension/int_extension.dart';
import 'package:flutter_bilibili/ui/shared/app_theme.dart';
import 'package:flutter_bilibili/ui/shared/image_assets.dart';
import 'package:flutter_bilibili/ui/shared/size_fit.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

void main() async {
  /// 导入和初始化
  WidgetsFlutterBinding.ensureInitialized();
  await FlutterDownloader.initialize(debug: debug, ignoreSsl: true);
  runApp(MaterialApp(
    home: VideoShare(), // here
    navigatorObservers: [FlutterSmartDialog.observer],
    // here
    builder: FlutterSmartDialog.init(),
  ));
}

const debug = true;

class VideoShare extends StatefulWidget with WidgetsBindingObserver {
  @override
  _VideoShareState createState() => _VideoShareState();
}

class _VideoShareState extends State<VideoShare> {
  late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
  List<_TaskInfo>? _tasks;
  late List<_ItemHolder> _items;
  late bool _isLoading;
  late bool _permissionReady;
  late String _localPath;
  ReceivePort _port = ReceivePort();

  final _videos = [
    {
      'name': 'zzzzzz',
      'link': 'https://www.w3school.com.cn/example/html5/mov_bbb.mp4'
    },
  ];

  @override
  void initState() {
    HYSizeFit.initialize();

    ///推送初始化
    flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
    var android = AndroidInitializationSettings('@mipmap/ic_launcher');
    var iOS = IOSInitializationSettings();
    var initSettings = InitializationSettings(android: android, iOS: iOS);
    flutterLocalNotificationsPlugin.initialize(initSettings);

    ///缓存初始化
    _bindBackgroundIsolate();
    FlutterDownloader.registerCallback(downloadCallback);
    _isLoading = true;
    _permissionReady = false;
    _prepare();

    super.initState();
  }

  @override
  void dispose() {
    _unbindBackgroundIsolate();
    super.dispose();
  }

  void _bindBackgroundIsolate() {
    bool isSuccess = IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');
    if (!isSuccess) {
      _unbindBackgroundIsolate();
      _bindBackgroundIsolate();
      return;
    }
    _port.listen((dynamic data) {
      if (debug) {
        print('UI Isolate Callback: $data');
      }
      String? id = data[0];
      DownloadTaskStatus? status = data[1];
      int? progress = data[2];

      if (_tasks != null && _tasks!.isNotEmpty) {
        final task = _tasks!.firstWhere((task) => task.taskId == id);
        setState(() {
          task.status = status;
          task.progress = progress;
        });
      }
    });
  }

  void _unbindBackgroundIsolate() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
  }

  static void downloadCallback(
      String id, DownloadTaskStatus status, int progress) {
    if (debug) {
      print(
          'Background Isolate Callback: task ($id) is in status ($status) and process ($progress)');
    }
    final SendPort send =
        IsolateNameServer.lookupPortByName('downloader_send_port')!;
    send.send([id, status, progress]);
  }

  Future<void> _prepare() async {
    ///加载所有下载任务
    final tasks = await FlutterDownloader.loadTasks();

    int count = 0;
    _tasks = [];
    _items = [];

    _tasks!.addAll(_videos
        .map((video) => _TaskInfo(name: video['name'], link: video['link'])));

    for (int i = count; i < _tasks!.length; i++) {
      _items.add(_ItemHolder(name: _tasks![i].name, task: _tasks![i]));
      count++;
    }

    for (var task in tasks!) {
      for (_TaskInfo info in _tasks!) {
        if (info.link == task.url) {
          info.taskId = task.taskId;
          info.status = task.status;
          info.progress = task.progress;
        }
      }
    }

    _permissionReady = await _checkPermission();

    if (_permissionReady) {
      await _prepareSaveDir();
    }

    setState(() {
      _isLoading = false;
    });
  }

  Future<void> _prepareSaveDir() async {
    _localPath = (await _findLocalPath())! + "/bilibili_download";
    final savedDir = Directory(_localPath);
    print(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
  }

  Future<String?> _findLocalPath() async {
    String? externalStorageDirPath;
    if (Platform.isAndroid) {
      final directory = await getTemporaryDirectory();
      externalStorageDirPath = directory.path;
    } else if (Platform.isIOS) {
      externalStorageDirPath =
          (await getApplicationDocumentsDirectory()).absolute.path;
    }
    return externalStorageDirPath;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          ///底部弹窗
          buildVideoShare();
        },
      ),
    );
  }

  Widget buildShareButton(String img, String text) {
    return Container(
      padding: EdgeInsets.only(right: 10.px, top: 5.px),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          CircleAvatar(
            radius: 20.px,
            backgroundImage: AssetImage(img),
          ),
          SizedBox(
            height: 15.px,
          ),
          Text(
            text,
            style: TextStyle(
              color: HYAppTheme.norGrayColor,
              fontSize: HYAppTheme.xxSmallFontSize,
            ),
          )
        ],
      ),
    );
  }

  ///视频分享
  void buildVideoShare() {
    showModalBottomSheet(
      context: context,
      builder: (ctx) {
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              padding: EdgeInsets.only(
                left: 20.px,
                top: 15.px,
              ),
              color: Theme.of(context).canvasColor,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      Text(
                        "分享",
                        style: TextStyle(
                          fontSize: HYAppTheme.xxSmallFontSize,
                          color: Colors.black,
                        ),
                      ),
                    ],
                  ),
                  SizedBox(
                    height: 10.px,
                  ),
                  Container(
                    height: 90.px,
                    child: ListView(
                      scrollDirection: Axis.horizontal,
                      children: [
                        buildShareButton(
                          ImageAssets.biliSocializeWxChatPNG,
                          "微信",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeWxMomentPNG,
                          "朋友圈",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "下载分享",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeQqChatPNG,
                          "QQ",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeQqZonePNG,
                          "QQ空间",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeDynamicPNG,
                          "动态",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "消息",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "图片分享",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "标记点分享",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeCopyPNG,
                          "复制链接",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "更多",
                        ),
                      ],
                    ),
                  ),
                  Container(
                    height: 90.px,
                    child: ListView(
                      scrollDirection: Axis.horizontal,
                      children: [
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "稍后再看",
                        ),
                        GestureDetector(
                          onTap: () {
                            Navigator.pop(context);
                            buildDownloadCache();
                          },
                          child: buildShareButton(
                              ImageAssets.biliSocializeGenericPNG, "缓存"),
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "倍速播放",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "播放设置",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "听视频",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "后台播放",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "笔记",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "举报",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "我不想看",
                        ),
                        buildShareButton(
                          ImageAssets.biliSocializeGenericPNG,
                          "播放反馈",
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            Container(
              child: TextButton(
                onPressed: () {},
                child: Container(
                  alignment: Alignment.center,
                  child: Text(
                    "取消",
                    style: TextStyle(color: Colors.black),
                  ),
                  height: 40.px,
                  width: double.infinity,
                ),
              ),
            )
          ],
        );
      },
      constraints: BoxConstraints(maxHeight: 300.px),
    );
  }

  ///下载缓存
  void buildDownloadCache() {
    showModalBottomSheet(
        context: context,
        builder: (ctx) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                padding: EdgeInsets.symmetric(
                  horizontal: 20.px,
                  vertical: 15.px,
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      "下载缓存",
                      style: TextStyle(
                        color: Colors.black,
                        fontSize: HYAppTheme.xSmallFontSize,
                      ),
                    ),
                    Icon(
                      Icons.close,
                      size: 15.px,
                    ),
                  ],
                ),
              ),
              Container(
                decoration: BoxDecoration(
                  border: BorderDirectional(
                      top: BorderSide(
                        color: HYAppTheme.norGrayColor,
                        width: .5,
                      ),
                      bottom: BorderSide(
                          color: HYAppTheme.norGrayColor, width: .5)),
                ),
                padding:
                    EdgeInsets.symmetric(vertical: 10.px, horizontal: 5.px),
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Text(
                          "当前画质：",
                          style: TextStyle(
                            color: HYAppTheme.norGrayColor,
                            fontSize: HYAppTheme.xxSmallFontSize,
                          ),
                        ),
                        const Text(
                          "720高清",
                          style: TextStyle(
                            color: Colors.black,
                            fontSize: HYAppTheme.xxSmallFontSize,
                          ),
                        ),
                        SizedBox(
                          width: 5.px,
                        ),
                        Image.asset(
                          ImageAssets.icArrowUpPNG,
                          width: 10.px,
                          height: 10.px,
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 15.px,
                    ),
                    Container(
                      padding: EdgeInsets.all(10.px),
                      height: 40.px,
                      child: ListView(
                        scrollDirection: Axis.horizontal,
                        children: [
                          Text(
                            "8K大会员",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                          Text(
                            "4K大会员",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                          Text(
                            "1080P高清",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                          Text(
                            "720P高清",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                          Text(
                            "480P高清",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                          Text(
                            "360P高清",
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: HYAppTheme.xSmallFontSize,
                            ),
                          ),
                          SizedBox(
                            width: 30.px,
                          ),
                        ],
                      ),
                    ),
                    Builder(
                      builder: (context) {
                        return Container(
                          height: 150.px,
                          child: _isLoading
                              ? const Center(
                                  child: CircularProgressIndicator(
                                    color: HYAppTheme.norTextColors,
                                  ),
                                )
                              : _permissionReady
                                  ? _buildDownloadList()
                                  : _buildNoPermissionWarning(),
                        );
                      },
                    ),
                  ],
                ),
              ),
              Container(
                padding: EdgeInsets.symmetric(vertical: 15.px),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Text(
                      "缓存全部",
                      style: TextStyle(
                          color: Colors.black,
                          fontSize: HYAppTheme.smallFontSize),
                    ),
                    Container(
                      height: 25.px,
                      width: .5,
                      padding: EdgeInsets.symmetric(vertical: 5.px),
                      color: HYAppTheme.norGrayColor,
                    ),
                    GestureDetector(
                      onTap: () async {
                        // Navigator.of(context).pushNamed(HYOfflineCacheScreen.routeName ,arguments: _localPath);
                        Stream<FileSystemEntity> fileList =
                            Directory(_localPath).list();
                        fileList.listen((event) {
                          print('$event');
                          FileSystemEntityType type =
                              FileSystemEntity.typeSync(event.path);
                          print('$type');
                        });
                      },
                      child: Text(
                        "查看缓存",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: HYAppTheme.smallFontSize),
                      ),
                    ),
                  ],
                ),
              )
            ],
          );
        },
        constraints: BoxConstraints(maxHeight: 350.px));
  }

  Widget _buildNoPermissionWarning() => Container(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 24.0),
                child: Text(
                  'Please grant accessing storage permission to continue -_-',
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.blueGrey, fontSize: 18.0),
                ),
              ),
              SizedBox(
                height: 32.0,
              ),
              TextButton(
                  onPressed: () {
                    _retryRequestPermission();
                  },
                  child: Text(
                    'Retry',
                    style: TextStyle(
                        color: Colors.blue,
                        fontWeight: FontWeight.bold,
                        fontSize: 20.0),
                  ))
            ],
          ),
        ),
      );

  Widget _buildDownloadList() {
    return ListView(
      children: _items.map((item) {
        return DownloadItem(
          data: item,
          onItemClick: (task) {
            _openDownloadedFile(task).then((success) {
              if (!success) {
                ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Cannot open this file')));
              }
            });
          },
          onActionClick: (task) {
            if (task.status == DownloadTaskStatus.undefined) {
              _requestDownload(task);
            } else if (task.status == DownloadTaskStatus.running) {
              _pauseDownload(task);
            } else if (task.status == DownloadTaskStatus.paused) {
              _resumeDownload(task);
            } else if (task.status == DownloadTaskStatus.complete) {
              _delete(task);
            } else if (task.status == DownloadTaskStatus.failed) {
              _retryDownload(task);
            }
          },
        );
      }).toList(),
    );
  }

  Future<void> _retryRequestPermission() async {
    final hasGranted = await _checkPermission();

    if (hasGranted) {
      await _prepareSaveDir();
    }

    setState(() {
      _permissionReady = hasGranted;
    });
  }

  void _requestDownload(_TaskInfo task) async {
    task.taskId = await FlutterDownloader.enqueue(
      url: task.link!,
      headers: {"auth": "test_for_sql_encoding"},
      savedDir: _localPath,
      showNotification: true,
      openFileFromNotification: true,
      saveInPublicStorage: true,
    );
  }

  void _pauseDownload(_TaskInfo task) async {
    await FlutterDownloader.pause(taskId: task.taskId!);
  }

  void _resumeDownload(_TaskInfo task) async {
    String? newTaskId = await FlutterDownloader.resume(taskId: task.taskId!);
    task.taskId = newTaskId;
  }

  void _retryDownload(_TaskInfo task) async {
    String? newTaskId = await FlutterDownloader.retry(taskId: task.taskId!);
    task.taskId = newTaskId;
  }

  Future<bool> _openDownloadedFile(_TaskInfo? task) {
    if (task != null) {
      return FlutterDownloader.open(taskId: task.taskId!);
    } else {
      return Future.value(false);
    }
  }

  void _delete(_TaskInfo task) async {
    await FlutterDownloader.remove(
        taskId: task.taskId!, shouldDeleteContent: true);
    await _prepare();
    setState(() {});
  }

  Future<bool> _checkPermission() async {
    if (Platform.isIOS) return true;
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    final platform = Theme.of(context).platform;
    AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
    if (platform == TargetPlatform.android) {
      final statusStorage = await Permission.storage.status;
      // final statusManageStorage = await Permission.manageExternalStorage.status;
      if (statusStorage != PermissionStatus.granted) {
        final resultStorage = await Permission.storage.request();
        // final resultManageExternalStorage =
        //     await Permission.manageExternalStorage.request();
        if (resultStorage == PermissionStatus.granted) {
          return true;
        } else {
          return false;
        }
      } else {
        return true;
      }
    } else {
      return true;
    }
  }

  ///发送本地推送
  void send(String title, String body) {
    // 构建描述
    var androidDetails = const AndroidNotificationDetails('id描述', '名称描述',
        importance: Importance.max, priority: Priority.high);
    var iosDetails = const IOSNotificationDetails();
    var details = NotificationDetails(android: androidDetails, iOS: iosDetails);

    // 显示通知, 第一个参数是id,id如果一致则会覆盖之前的通知
    flutterLocalNotificationsPlugin.show(
        DateTime.now().millisecondsSinceEpoch >> 10, title, body, details);
  }
}

class _TaskInfo {
  final String? name;
  final String? link;

  String? taskId;
  int? progress = 0;
  DownloadTaskStatus? status = DownloadTaskStatus.undefined;

  _TaskInfo({this.name, this.link});
}

class _ItemHolder {
  final String? name;
  final _TaskInfo? task;

  _ItemHolder({this.name, this.task});
}

class DownloadItem extends StatefulWidget {
  final _ItemHolder? data;
  final Function(_TaskInfo?)? onItemClick;
  final Function(_TaskInfo)? onActionClick;

  DownloadItem({this.data, this.onItemClick, this.onActionClick});

  @override
  State<DownloadItem> createState() => _DownloadItemState();
}

class _DownloadItemState extends State<DownloadItem> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (widget.data?.task?.status == DownloadTaskStatus.complete) {
          SmartDialog.showToast("视频已经缓存完成~");
          widget.onItemClick!(widget.data!.task);
        } else if (widget.data?.task?.status == DownloadTaskStatus.running) {
          SmartDialog.showToast("该视频已经添加至正在缓存列表~");
        } else {
          widget.onActionClick!(widget.data!.task!);
        }
        if (mounted) setState(() {});
      },
      child: Stack(
        children: [
          Container(
            width: double.infinity,
            alignment: Alignment.centerLeft,
            child: Text(
              widget.data!.name!,
              maxLines: 1,
              softWrap: true,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: HYAppTheme.smallFontSize,
              ),
            ),
            margin: EdgeInsets.symmetric(vertical: 5.px, horizontal: 8.px),
            padding: EdgeInsets.symmetric(vertical: 5.px, horizontal: 10.px),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(3.px)),
              border: Border.all(color: HYAppTheme.norTextColors),
            ),
          ),
          Positioned(
            child: _buildActionForTask(widget.data!.task!),
            bottom: 0,
            right: 2.px,
          ),
        ],
      ),
    );
  }

  Widget _buildActionForTask(_TaskInfo task) {
    if (task.status == DownloadTaskStatus.paused) {
      return CircleAvatar(
        radius: 7.px,
        backgroundImage: AssetImage(ImageAssets.icVideoDownloadStopPNG),
      );
    } else if (task.status == DownloadTaskStatus.complete) {
      return CircleAvatar(
        radius: 7.px,
        backgroundImage: AssetImage(ImageAssets.icVideoDownloadCompletePNG),
      );
    } else if (task.status == DownloadTaskStatus.canceled) {
      return Container();
    } else if (task.status == DownloadTaskStatus.failed) {
      return CircleAvatar(
        radius: 7.px,
        backgroundImage: AssetImage(ImageAssets.icVideoDownloadErrorPNG),
      );
    } else if (task.status == DownloadTaskStatus.enqueued) {
      return Container();
    } else if (task.status == DownloadTaskStatus.running) {
      return CircleAvatar(
        radius: 7.px,
        backgroundImage: AssetImage(ImageAssets.icVideoDownloadProcessingPNG),
      );
    } else if (task.status == DownloadTaskStatus.undefined) {
      return Container();
    } else {
      return Container();
    }
  }
}
